package com.cskaoyan.wordmemorize.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cskaoyan.wordmemorize.common.aspect.operate.OperateLog;
import com.cskaoyan.wordmemorize.common.aspect.operate.OperateLogConstant;
import com.cskaoyan.wordmemorize.common.constant.ResultCodeEnum;
import com.cskaoyan.wordmemorize.common.exception.BusinessException;
import com.cskaoyan.wordmemorize.converter.VocCategoryConverter;
import com.cskaoyan.wordmemorize.dao.entity.VocBookDO;
import com.cskaoyan.wordmemorize.dao.entity.VocCategoryDO;
import com.cskaoyan.wordmemorize.dao.mapper.VocBookMapper;
import com.cskaoyan.wordmemorize.dao.mapper.VocCategoryMapper;
import com.cskaoyan.wordmemorize.dto.admin.DeleteBookCategoryOperateDTO;
import com.cskaoyan.wordmemorize.dto.admin.PageDTO;
import com.cskaoyan.wordmemorize.dto.admin.VocCategoryDTO;
import com.cskaoyan.wordmemorize.request.BatchDeleteCommand;
import com.cskaoyan.wordmemorize.request.PageRequest;
import com.cskaoyan.wordmemorize.request.VocCategoryCommand;
import com.cskaoyan.wordmemorize.service.VocCategoryService;
import org.mapstruct.ap.shaded.freemarker.template.utility.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 目录与书籍是一对多的关系
 */
@Service
public class VocCategoryServiceImpl extends ServiceImpl<VocCategoryMapper, VocCategoryDO> implements VocCategoryService {

    @Autowired
    private VocCategoryConverter vocCategoryConverter;

    @Autowired
    private VocCategoryMapper vocCategoryMapper;

    @Autowired
    private VocBookMapper vocBookMapper;

    @Override
    public PageDTO<VocCategoryDTO> getBookCategories(PageRequest pageQuery) {
        System.out.println("以下是分页查询书籍类目");
        System.out.println("书籍目录getPageNum() = " + pageQuery.getPageNum());
        if (pageQuery.getPageNum() == null) {
            // 查询所有的书籍类目
            List<VocCategoryDO> vocCategoryDOs = vocCategoryMapper.selectList(null);

            getBookCount(vocCategoryDOs);

            return vocCategoryConverter.bookCategoryList2Page(vocCategoryDOs, (long) vocCategoryDOs.size());
        }

        // 分页查询
        Page<VocCategoryDO> pageParam = new Page<>(pageQuery.getPageNum(), pageQuery.getCount());
        LambdaQueryWrapper<VocCategoryDO> vocCategoryWrapper = new LambdaQueryWrapper<>();
        //模糊匹配
        if (StringUtil.emptyToNull(pageQuery.getKeyword()) != null) {
            vocCategoryWrapper.like(VocCategoryDO::getCategoryName, pageQuery.getKeyword());
        }
        Page<VocCategoryDO> vocCategoryPage = vocCategoryMapper.selectPage(pageParam, vocCategoryWrapper);

        List<VocCategoryDO> records = vocCategoryPage.getRecords();
        getBookCount(records);

        return vocCategoryConverter.bookCategoryList2Page(records, vocCategoryPage.getTotal());
    }

    /**
     * 获取书籍数量
     * @param list
     */
    private void getBookCount(List<VocCategoryDO> list) {
        list.forEach(vocCategoryDO -> {
            LambdaQueryWrapper<VocBookDO> vocBookDOQueryWrapper = new LambdaQueryWrapper<>();
            vocBookDOQueryWrapper.eq(VocBookDO::getBcId, vocCategoryDO.getId());
            Long count = vocBookMapper.selectCount(vocBookDOQueryWrapper);
            System.out.println("书籍数量 = " + count);
            vocCategoryDO.setBookCount(Integer.valueOf(count + ""));
        });
    }

    @Override
    public VocCategoryDTO getBookCategory(Long categoryId) {
        System.out.println("以下是获取指定的书籍类目");
        LambdaQueryWrapper<VocCategoryDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(VocCategoryDO::getId, categoryId);
        VocCategoryDO vocCategoryDO = vocCategoryMapper.selectOne(queryWrapper);

        //获取该书籍目录下的书籍数量
        LambdaQueryWrapper<VocBookDO> vocBookDOQueryWrapper = new LambdaQueryWrapper<>();
        vocBookDOQueryWrapper.eq(VocBookDO::getBcId, categoryId);
        Long count = vocBookMapper.selectCount(vocBookDOQueryWrapper);



        vocCategoryDO.setBookCount(Integer.valueOf(count + ""));
        return vocCategoryConverter.bookCategoryEntity2DTO(vocCategoryDO);

    }

    @OperateLog(dateType = "类目", operateType = OperateLogConstant.OPERATE_ADD)
    @Override
    public Long addBookCategory(VocCategoryCommand command) {
        System.out.println("以下是新增类目");
        if ("".equals(command.getId())){
            command.setId(null);
        }
        VocCategoryDO vocCategoryDO = vocCategoryConverter.bookCategoryCommand2Entity(command);
        int insert = vocCategoryMapper.insert(vocCategoryDO);
        if (insert == 0) {
            throw new BusinessException(ResultCodeEnum.FAIL);
        }
        return null;
    }

    @OperateLog(dateType = "类目", operateType = OperateLogConstant.OPERATE_UPDATE)
    @Override
    public void updateBookCategory(VocCategoryCommand command) {
        System.out.println("以下是更新类目");
        VocCategoryDO vocCategoryDO = vocCategoryConverter.bookCategoryCommand2Entity(command);

        int update = vocCategoryMapper.updateById(vocCategoryDO);
        if (update == 0) {
            throw new BusinessException(ResultCodeEnum.FAIL);
        }
    }

    @OperateLog(dateType = "类目", operateType = OperateLogConstant.OPERATE_SINGLE_DELETE)
    @Transactional
    @Override
    public DeleteBookCategoryOperateDTO deleteBookCategory(Long categoryId) {
        System.out.println("以下是删除指定的书籍类目");
        VocCategoryDO vocCategoryDO = vocCategoryMapper.selectById(categoryId);
        int row1 = vocCategoryMapper.deleteById(categoryId);
        //连表删除，删除voc_book表中的相关书籍类目
        Map<String, Object> map = new HashMap<>();
        map.put("bc_id", categoryId);
        int row2 = vocBookMapper.deleteByMap(map);

        if (row1 <= 0 || row2 < 0) {
            throw new BusinessException(ResultCodeEnum.FAIL);
        }
        return vocCategoryConverter.bookCategoryDOToDeleteCategoryDTO(vocCategoryDO);
    }

    @OperateLog(dateType = "类目", operateType = OperateLogConstant.OPERATE_BATCH_DELETE)
    @Transactional
    @Override
    public List<DeleteBookCategoryOperateDTO> deleteBookCategories(BatchDeleteCommand command) {
        System.out.println("以下是批量删除书籍类目");
        List<VocCategoryDO> vocCategoryDOS = vocCategoryMapper.selectByIds(command.getIds());
        int row1 = vocCategoryMapper.deleteByIds(command.getIds());
        //连表删除，删除voc_book表中的相关书籍类目
        LambdaQueryWrapper<VocBookDO> bookDOQueryWrapper = new LambdaQueryWrapper<>();
        bookDOQueryWrapper.in(VocBookDO::getBcId, command.getIds());
        int row2 = vocBookMapper.delete(bookDOQueryWrapper);

        if (row1 <= 0 || row2 < 0) {
            throw new BusinessException(ResultCodeEnum.FAIL);
        }
        return vocCategoryConverter.bookCategoryDOsToDeleteCategoryDTOs(vocCategoryDOS);
    }
}
